﻿using System;
using System.Collections.Generic;
using AutoMapper;
using CollegeSim.CourseScheduler.Domain.DTO;
using CollegeSim.CourseScheduler.Domain.Entities;
using CollegeSim.CourseScheduler.Domain.Interfaces;
using CollegeSim.CourseScheduler.Domain.Interfaces.Repositories;

namespace CollegeSim.CourseScheduler.Domain.Services
{
    // Author: Ryan Redburn
    // Project: Course Scheduler
    // Date: 2/8/2014

    public class InstructorService
    {
        #region [ Fields ]

        private readonly IInstructorRepository _instructorRepository;

        #endregion

        #region [ Constructors ]

        // Requires an instance of IInstructorRepository
        public InstructorService(IInstructorRepository instructorRepository)
        {
            _instructorRepository = instructorRepository;
        }

        #endregion

        #region [ Methods ]

        /// <summary>
        /// Returns a list of all Instructors
        /// </summary>
        /// <returns>List of InstructorDto</returns>
        public List<InstructorDto> GetAll()
        {
            // If invalid data is received from persistence an exception is thrown to indicate thusly

            try
            {
                var instructors = Mapper.Map<List<Instructor>>(_instructorRepository.FindAll()); // Validate data
                return Mapper.Map<List<InstructorDto>>(instructors);
            }
            catch (ArgumentNullException)
            {
                throw new InvalidOperationException("Invalid data may have been received from persistence.");
            }
            catch (ArgumentOutOfRangeException)
            {
                throw new InvalidOperationException("Invalid data may have been received from persistence.");
            }
        }

        /// <summary>
        /// Returns an instructor with the given id.
        /// </summary>
        /// <param name="instructorId">Integer instructor id</param>
        /// <returns>InstructorDto</returns>
        public InstructorDto GetById(int instructorId)
        {
            // Throws an exception for invalid instructor id value
            if  (instructorId < 0)
                throw new ArgumentOutOfRangeException("instructorId",
                    "instructorId does not accept an integer less than zero as an argument.");

            var instructor = Mapper.Map<Instructor>(_instructorRepository.FindById(instructorId));
            return Mapper.Map<InstructorDto>(instructor);
        }

        /// <summary>
        /// Validates and commits an instructor for persistence.
        /// Throws exceptions for invalid data.
        /// </summary>
        /// <param name="newInstructor">New instructor to save.</param>
        public void CommitInstructor(InstructorDto newInstructor)
        {
            var instructor = Mapper.Map<Instructor>(newInstructor);
            _instructorRepository.Insert(Mapper.Map<InstructorDto>(instructor));
        }

        #endregion
    }
}
